<template>
  <div class="device-root">
    <ViewHead></ViewHead>
    <el-row class="root-content">
      <el-col :span="5" class="left-panel yj">
        <div id="device-root-left-panel">
          <el-scrollbar style="height:100%" class="yj" ref="leftscrollbar">
            <el-tree ref="nodeTree" :expand-on-click-node="false" :data="nodeTreeData" @node-click="onNodeTreeClick" @node-drop="handleDragComplate" :allow-drop="handleAllowDrop" highlight-current :props="defaultProps" draggable>
              <span class="tree-node" slot-scope="{ node, data }">
                <span :title="node.label">{{ node.label }}</span>
                <span v-show="config.rights.device_node_manager && data.id !== config.user.unknow_node_id" class="tree-node-menu">
                  <el-dropdown size="mini">
                    <span class="el-dropdown-link">
                      <i class="el-icon-arrow-down el-icon-more" style="color:#409EFF"></i>
                    </span>
                    <el-dropdown-menu slot="dropdown">
                      <div @click.stop="onTreeNodeMenu('add',node,data)">
                        <el-dropdown-item command="add">添加节点</el-dropdown-item>
                      </div>
                      <div @click.stop="onTreeNodeMenu('adddevice',node,data)">
                        <el-dropdown-item command="adddevice">添加设备</el-dropdown-item>
                      </div>
                      <div v-show="data.pid !== '0'" @click.stop="onTreeNodeMenu('rename',node,data)">
                        <el-dropdown-item command="rename">重命名</el-dropdown-item>
                      </div>
                      <div v-show="data.pid !== '0'" @click.stop="onTreeNodeMenu('del',node,data)">
                        <el-dropdown-item command="del" style="color:#F56C6C;">删除</el-dropdown-item>
                      </div>
                    </el-dropdown-menu>
                  </el-dropdown>
                </span>
              </span>
            </el-tree>
          </el-scrollbar>
        </div>
      </el-col>
      <el-col :span="19" style="height:100%">
        <div id="device-root-right-panel" style="height:100%">
          <el-scrollbar ref="rightscrollbar" style="height:100%">
            <div class="query-menu yj" :class="isFixedTop && 'query-menu-fixed-top'">
              <div class="divline" style="width: 150px">
                <el-input v-model="queryForm.name" placeholder="名称" clearable size="mini"></el-input>
              </div>
              <div class="divline" style="width: 150px">
                <el-input v-model="queryForm.devdesc" placeholder="备注" clearable size="mini"></el-input>
              </div>
              <div class="divline" style="width: 150px">
                <el-input v-model="queryForm.ip" placeholder="IP地址" clearable size="mini"></el-input>
              </div>
              <div class="divline" style="width:100px;">
                <el-select v-model="queryForm.isonline" placeholder="状态" size="mini">
                  <el-option label="所有" value="none"></el-option>
                  <el-option label="在线" value="online"></el-option>
                  <el-option label="控制中" value="ing"></el-option>
                  <el-option label="离线" value="offline"></el-option>
                </el-select>
              </div>
              <div class="divline" style="width:100px;">
                <el-button @click="onQueryDeviceList" type="primary" icon="el-icon-search" size="mini">查询</el-button>
              </div>
            </div>
            <div v-show="devices.length === 0" class="empty">
              <h2>无设备</h2>
            </div>
            <div class="device-list">
              <DeviceItem :onTopDevice="onTopDevice" :onDeleteDevice="onDeleteDevice" v-for="item in devices" :data="item" :key="item.id"></DeviceItem>
            </div>
            <div style="height:20px;"></div>
          </el-scrollbar>
        </div>
      </el-col>
    </el-row>

    <el-dialog title="设备信息" :visible.sync="adddeviceDialog.visible" width="50%" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
      <div style="padding-left:50px; padding-right:50px;">
        <el-form size="mini" label-width="100px">
          <el-form-item label="设备名称 *">
            <el-input placeholder="请输入设备名称" v-model="adddeviceDialog.name"></el-input>
          </el-form-item>
          <el-form-item label="备注 *">
            <el-input placeholder="请输入备注信息" v-model="adddeviceDialog.devdesc"></el-input>
          </el-form-item>
          <el-form-item label="IP *">
            <el-input placeholder="请输入IP地址" v-model="adddeviceDialog.ip"></el-input>
          </el-form-item>
          <el-form-item label="端口 *">
            <el-input style="width:200px;" type="number" placeholder="请输入端口" v-model="adddeviceDialog.port"></el-input>
          </el-form-item>
          <el-form-item label="协议类型">
            <el-radio-group v-model="adddeviceDialog.protocol">
              <el-radio label="VNC">VNC协议</el-radio>
              <el-radio label="RDP">RDP协议</el-radio>
              <el-radio label="SSH">SSH</el-radio>
              <el-radio label="TELNET">TELNET</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item v-show="adddeviceDialog.protocol === 'RDP' || adddeviceDialog.protocol === 'SSH'" label="登录账号">
            <el-input v-model="adddeviceDialog.username"></el-input>
          </el-form-item>
          <el-form-item v-show="adddeviceDialog.protocol === 'RDP' || adddeviceDialog.protocol === 'SSH'" label="密码">
            <el-input show-password v-model="adddeviceDialog.password"></el-input>
          </el-form-item>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button size="mini" @click="closeTreeNodeDevice">取 消</el-button>
        <el-button size="mini" type="primary" @click="onAddDevice">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import ViewHead from "~/base/ViewHead.vue";
import DeviceItem from "~/views/device/DeviceItem.vue";

export default {
  name: "Device",
  components: {
    ViewHead,
    DeviceItem,
  },
  data() {
    return {
      device_node_select: false,
      device_node_manager: false,
      device_device_select: false,
      device_device_manager: false,
      device_remotecpe: false,
      active: true,
      devices: [],
      lastTreeSelectData: null,
      isFixedTop: false,
      queryForm: {
        name: "",
        ip: "",
        devdesc: "",
        isonline: "none",
      },
      nodeTreeData: [],
      defaultProps: {
        children: "children",
        label: "label",
      },
      adddeviceDialog: {
        visible: false,
        devdesc: "",
        protocol: "VNC",
        name: "",
        ip: "",
        port: "",
        username: "",
        password: "",
      },
    };
  },
  methods: {
    onAddDevice() {
      if (
        !this.adddeviceDialog.name ||
        !this.adddeviceDialog.devdesc ||
        !this.adddeviceDialog.ip ||
        !this.adddeviceDialog.port
      ) {
        this.$message({
          type: "warning",
          message: "参数填写未完整",
        });
        return;
      }

      if (
        this.adddeviceDialog.protocol == "RDP" ||
        this.adddeviceDialog.protocol == "SSH"
      ) {
        if (!this.adddeviceDialog.username || !this.adddeviceDialog.password) {
          this.$message({
            type: "warning",
            message: "参数填写未完整",
          });
          return;
        }
      }

      this.utils.http(
        "post",
        "/webapi/device/add",
        { nodeId: this.lastTreeSelectData.data.id, ...this.adddeviceDialog },
        (resp) => {
          this.closeTreeNodeDevice();
          this.devices.unshift(resp);
        }
      );
    },
    onTopDevice(id) {
      for (let i = 0; i < this.devices.length; i++) {
        const item = this.devices[i];
        if (item.id === id) {
          this.devices.splice(i, 1);
          this.devices.unshift(item);
          break;
        }
      }
    },
    onDeleteDevice(id) {
      for (let i = 0; i < this.devices.length; i++) {
        const item = this.devices[i];
        if (item.id === id) {
          this.devices.splice(i, 1);
          break;
        }
      }
    },
    onQueryDeviceList() {
      if (this.device_device_select) {
        this.loadDeviceListByNodeid(this.lastTreeSelectData.data.id);
      }
    },
    handleAllowDrop(draggingNode, dropNode) {
      if (!this.config.rights.device_node_manager) {
        return false;
      }
      if (
        draggingNode.data.pid === "0" ||
        dropNode.data.pid === "0" ||
        draggingNode.data.id === this.config.user.unknow_node_id
      ) {
        return false;
      }

      return true;
    },
    handleDragComplate(before, after, inner) {
      const data = { id: before.data.id };
      if (inner === "inner") {
        data.targetId = after.data.id;
        data.list = after.childNodes;
      } else {
        if (after.parent.data.id) {
          data.targetId = after.parent.data.id;
        } else {
          data.targetId = "-9";
        }
        data.list = after.parent.childNodes;
      }
      const templist = [];
      for (const item of data.list) {
        templist.push(item.data.id);
      }
      data.list = templist.join(",");

      this.utils.http("post", "/webapi/device/node/move", data, () => {});
    },
    addTreeNodeDevice() {
      this.adddeviceDialog.visible = true;
    },
    closeTreeNodeDevice() {
      this.adddeviceDialog.visible = false;
      this.adddeviceDialog.name = "";
      this.adddeviceDialog.devdesc = "";
      this.adddeviceDialog.ip = "";
      this.adddeviceDialog.port = "";
      this.adddeviceDialog.protocol = "VNC";
      this.adddeviceDialog.username = "";
      this.adddeviceDialog.password = "";
    },
    addTreeNode(node, data) {
      this.$prompt("", "请输入节点名称", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      })
        .then(({ value }) => {
          if (!value) {
            return;
          }
          this.utils.http(
            "post",
            "/webapi/device/node/add",
            {
              pid: data.id,
              title: value,
            },
            (resp) => {
              this.appendNode(data, {
                id: resp.id,
                title: resp.title,
                pid: data.id,
              });
            }
          );
        })
        .catch(() => {});
    },
    delTreeNode(node, data) {
      this.$confirm(`是否删除 ${data.label} 节点?`, "删除提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.utils.http(
            "post",
            "/webapi/device/node/delete",
            {
              id: data.id,
            },
            () => {
              const parent = node.parent;
              try {
                const children = parent.data.children || parent.data;
                const index = children.findIndex((d) => d.id === data.id);
                children.splice(index, 1);
              } catch (error) {
                const index = this.nodeTreeData.findIndex(
                  (d) => d.id === data.id
                );
                this.nodeTreeData.splice(index, 1);
              }
              this.lastTreeSelectData = null;
            }
          );
        })
        .catch(() => {});
    },
    renameTreeNode(node, data) {
      this.$prompt("", "请输入节点名称", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputValue: data.label,
      })
        .then(({ value }) => {
          if (!value) {
            return;
          }
          this.utils.http(
            "post",
            "/webapi/device/node/rename",
            {
              id: data.id,
              title: value,
            },
            () => {
              data.label = value;
            }
          );
        })
        .catch(() => {});
    },
    appendNode(node, cnode) {
      const newChild = { label: cnode.title, ...cnode, children: [] };
      if (!node.children) {
        this.$set(node, "children", []);
      }
      node.children.push(newChild);
    },
    loadNodeTreeData() {
      this.nodeTree = [];
      this.utils.http("get", "/webapi/device/node/tree", {}, (resp) => {
        this.nodeTreeData = resp;
        this.lastTreeSelectData = { data: this.nodeTreeData[0] };
        this.loadDeviceListByNodeid(this.nodeTreeData[0].id);
      });
    },
    onTreeNodeMenu(action, node, data) {
      if (action === "adddevice") {
        this.addTreeNodeDevice(node, data);
        return;
      }
      if (action === "add") {
        this.addTreeNode(node, data);
        return;
      }
      if (action === "rename") {
        this.renameTreeNode(node, data);
        return;
      }
      if (action === "del") {
        this.delTreeNode(node, data);
        return;
      }
    },
    onNodeTreeClick(node, data) {
      if (
        this.lastTreeSelectData !== null &&
        data.data.id === this.lastTreeSelectData.data.id
      ) {
        return;
      }
      this.lastTreeSelectData = data;
      this.loadDeviceListByNodeid(data.data.id);
    },
    makeLeftHeight() {
      return `${this.config.height - 65}px`;
    },
    makeRightHeight() {
      return `${this.config.height - 110}px`;
    },
    loadDeviceListByNodeid(nodeId) {
      this.utils.http(
        "get",
        "/webapi/device/node/list/get",
        {
          nodeId,
          name: this.queryForm.name,
          devdesc: this.queryForm.devdesc,
          ip: this.queryForm.ip,
          isonline: this.queryForm.isonline,
        },
        (resp) => {
          this.devices = resp;
        }
      );
    },
    getDeviceListStatusHandler() {
      const ids = [];
      for (const item of this.devices) {
        ids.push(item.id);
      }
      if (ids.length === 0) {
        return;
      }

      this.utils.http(
        "post",
        "/webapi/device/state/list/get",
        {
          ids: ids.join(","),
        },
        (resp) => {
          for (const item of this.devices) {
            const tempitem = resp[item.id];
            if (!tempitem) {
              continue;
            }
            if (item.isprober === "YES") {
              item.isonline = tempitem.isonline;
              item.isremote = tempitem.isremote;
              continue;
            }
            item.isremote = tempitem.isremote;
          }
        }
      );
    },
    getDeviceListStatusWork() {
      if (!this.active) {
        return;
      }

      setTimeout(() => {
        this.getDeviceListStatusHandler();
        this.getDeviceListStatusWork();
      }, 5000);
    },
  },
  mounted() {
    this.utils.refreshRootContentHeight();

    this.device_node_select = this.utils.hasRight("device_node_select");
    this.device_node_manager = this.utils.hasRight("device_node_manager");
    this.device_device_select = this.utils.hasRight("device_device_select");
    this.device_device_manager = this.utils.hasRight("device_device_manager");
    this.device_remotecpe = this.utils.hasRight("device_remotecpe");

    this.utils.on(this._uid, "refresh_height", () => {
      this.utils.refreshRootContentHeight();
      this.$nextTick(() => {
        this.$refs.leftscrollbar.update();
        this.$refs.rightscrollbar.update();
      });
    });

    let scrollbarEl = this.$refs.rightscrollbar.wrap;
    scrollbarEl.onscroll = () => {
      if (scrollbarEl.scrollTop > 10) {
        this.isFixedTop = true;
      } else {
        this.isFixedTop = false;
      }
    };

    if (this.device_node_select) {
      this.loadNodeTreeData();
    }

    if (this.device_device_select) {
      this.getDeviceListStatusWork();
    }
  },
  destroyed() {
    this.active = false;
    this.utils.unon(this._uid, "refresh_height");
  },
};
</script>

<style>
.device-root {
  height: 100%;
}

.device-root > .el-tabs {
  height: 100%;
}

.device-root > .el-tabs > .el-tabs__content {
  height: 100%;
}

.device-root .el-tabs__header {
  margin: 0px;
}

.device-root > .el-tabs > .el-tabs__content .el-tab-pane {
  height: 100%;
}

.device-root .left-panel {
  height: 100%;
  background-color: #ffffff;
  border: solid 1px #ffffff;
}

.device-root .query-menu {
  padding: 10px;
  background-color: #ffffff;
  margin-left: 5px;
  right: 0px;
}

.device-root .empty {
  text-align: center;
  padding-top: 100px;
}

.device-root .query-menu-fixed-top {
  position: fixed;
  background-color: #71b1f3;
  margin-right: 5px;
  z-index: 10;
}

#device-root-right-panel .el-scrollbar__wrap {
  overflow-x: hidden;
  height: 100%;
}

.device-root .device-list {
  margin-left: 5px;
  margin-top: 5px;
}

.device-root .device-list .item {
  padding-bottom: 3px;
  font-size: 14px;
}

.device-root .device-list .item .text {
  padding-top: 0.4%;
  color: #606266;
}

.device-root .device-list .item .delbtn {
  display: none;
}

.device-root .device-list .item:hover .delbtn {
  display: inline-block;
}

.device-root .device-list .item .el-card__body {
  padding: 10px;
}

.device-root .el-tree-node__content .tree-node .tree-node-menu {
  position: absolute;
  right: 10px;
  display: none;
}

.device-root .el-tree-node__content:hover .tree-node .tree-node-menu {
  display: inline-block;
}

.device-root
  .el-tree-node.is-current
  > .el-tree-node__content
  .tree-node
  .tree-node-menu {
  display: inline-block;
}
</style>